Simulasi Gelombang 1 Dimensi

Simulasi Gelombang 1 Dimensi#

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

# Parameter simulasi
c = 1.0           # Kecepatan gelombang
L = 10.0          # Panjang domain
T = 15.0          # Waktu simulasi
dx = 0.02         # Spasi grid spasial
dt = 0.01         # Interval waktu

x = np.arange(0, L, dx)  # Array posisi
t = np.arange(0, T, dt)  # Array waktu
Nx = len(x)              # Jumlah titik grid spasial
Nt = len(t)              # Jumlah langkah waktu

# Cek kondisi CFL
CFL = c * dt / dx
print("Angka CFL:", CFL)
if CFL >= 1:
    print("Peringatan: Simulasi mungkin tidak stabil!")

# Kondisi awal (Gaussian pulse)
x0 = L/2           # Posisi pusat gelombang
sigma = 0.5        # Lebar gelombang
y0 = np.exp(-(x - x0)**2 / (2*sigma**2))  # Displacement awal
vy0 = np.zeros(Nx) # Kecepatan awal (nol)

# Inisialisasi array solusi
y = np.zeros((Nx, Nt))
y[:, 0] = y0

# Mengisi langkah waktu pertama (n=1)
y[1:-1, 1] = y[1:-1, 0] + 0.5*(c*dt/dx)**2 * (y[2:, 0] - 2*y[1:-1, 0] + y[:-2, 0])

# Boundary condition tetap (Dirichlet)
y[0, 0] = y[0, 1] = 0
y[-1, 0] = y[-1, 1] = 0

# Iterasi waktu menggunakan metode finite difference
for n in range(1, Nt-1):
    # Update persamaan gelombang
    y[1:-1, n+1] = 2*y[1:-1, n] - y[1:-1, n-1] + (c*dt/dx)**2 * (y[2:, n] - 2*y[1:-1, n] + y[:-2, n])
    
    # Boundary condition
    y[0, n+1] = 0
    y[-1, n+1] = 0

# Membuat animasi
fig, ax = plt.subplots(figsize=(10,5))
line, = ax.plot(x, y[:,0], lw=2)
ax.set_xlim(0, L)
ax.set_ylim(-1.1, 1.1)
ax.set_xlabel('Posisi (x)')
ax.set_ylabel('Simpangan (y)')
ax.set_title('Simulasi Penjalaran Gelombang 1D')
ax.grid(True)

def animate(frame):
    line.set_ydata(y[:, frame])
    return line,

ani = FuncAnimation(fig, animate, frames=Nt, interval=20, blit=True)
plt.close()

# Untuk menampilkan animasi di Jupyter Notebook
from IPython.display import HTML
HTML(ani.to_jshtml())
Angka CFL: 0.5
Animation size has reached 20997120 bytes, exceeding the limit of 20971520.0. If you're sure you want a larger animation embedded, set the animation.embed_limit rc parameter to a larger value (in MB). This and further frames will be dropped.
# Parameter simulasi
c = 1.0           # Kecepatan gelombang
L = 10.0          # Panjang domain
T = 15.0          # Waktu simulasi
dx = 0.02         # Spasi grid spasial
dt = 0.01         # Interval waktu

x = np.arange(0, L, dx)  # Array posisi
t = np.arange(0, T, dt)  # Array waktu
Nx = len(x)              # Jumlah titik grid spasial
Nt = len(t)              # Jumlah langkah waktu

# Cek kondisi CFL
CFL = c * dt / dx
print("Angka CFL:", CFL)
if CFL >= 1:
    print("Peringatan: Simulasi mungkin tidak stabil!")

# Kondisi awal (Gaussian pulse)
x0 = L/2           # Posisi pusat gelombang
sigma = 0.5        # Lebar gelombang
y0 = -(x - x0) / (sigma**2) * np.exp(-(x - x0)**2 / (2 * sigma**2))  # Displacement awal
vy0 = np.zeros(Nx) # Kecepatan awal (nol)

# Inisialisasi array solusi
y = np.zeros((Nx, Nt))
y[:, 0] = y0

# Mengisi langkah waktu pertama (n=1)
y[1:-1, 1] = y[1:-1, 0] + 0.5*(c*dt/dx)**2 * (y[2:, 0] - 2*y[1:-1, 0] + y[:-2, 0])

# Boundary condition tetap (Dirichlet)
y[0, 0] = y[0, 1] = 0
y[-1, 0] = y[-1, 1] = 0

# Iterasi waktu menggunakan metode finite difference
for n in range(1, Nt-1):
    # Update persamaan gelombang
    y[1:-1, n+1] = 2*y[1:-1, n] - y[1:-1, n-1] + (c*dt/dx)**2 * (y[2:, n] - 2*y[1:-1, n] + y[:-2, n])
    
    # Boundary condition
    y[0, n+1] = 0
    y[-1, n+1] = 0

# Membuat animasi
fig, ax = plt.subplots(figsize=(10,5))
line, = ax.plot(x, y[:,0], lw=2)
ax.set_xlim(0, L)
ax.set_ylim(-1.1, 1.1)
ax.set_xlabel('Posisi (x)')
ax.set_ylabel('Simpangan (y)')
ax.set_title('Simulasi Penjalaran Gelombang 1D')
ax.grid(True)

def animate(frame):
    line.set_ydata(y[:, frame])
    return line,

ani = FuncAnimation(fig, animate, frames=Nt, interval=20, blit=True)
plt.close()

# Untuk menampilkan animasi di Jupyter Notebook
from IPython.display import HTML
HTML(ani.to_jshtml())
Angka CFL: 0.5
Animation size has reached 20987666 bytes, exceeding the limit of 20971520.0. If you're sure you want a larger animation embedded, set the animation.embed_limit rc parameter to a larger value (in MB). This and further frames will be dropped.